/************************************************************************/
/*                                                                      */
/************************************************************************/

#ifndef __BASE_H__
#define __BASE_H__

#if defined(WIN32)
#ifndef _WINDOWS_
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#endif
#endif

#ifndef BIT
#define BIT(x) (1 << (x))
#endif

#ifndef U8
typedef unsigned char       U8;
typedef unsigned short      U16;
typedef unsigned int        U32;
typedef unsigned __int64    U64;
typedef   signed char       S8;
typedef   signed short      S16;
typedef   signed int        S32;
typedef   signed __int64    S64;
typedef          float      F32;
typedef          double     F64;
#endif

// Some nice constants
#ifndef MAXINT
#define MAXINT		  	(0x7fffffff)
#endif

#ifndef MAXUINT
#define MAXUINT	  		(0xffffffff)
#endif

#define MINFLOAT32	  	(3.39e-38f)
#define MAXFLOAT32		(3.39e38f)

#define MINFLOAT64 		(1.8e-308)
#define MAXFLOAT64 		(1.8e308)

#define MINFLOAT	  		MINFLOAT32
#define MAXFLOAT	  		MAXFLOAT32

#ifndef BOOL
typedef	int					BOOL;
#define TRUE				1
#define FALSE				0
#endif

#if defined(WIN32)
//----------------------------------------------------------------------------------------------------------------------------
#pragma warning( disable : 4244 )
#pragma warning( disable : 4251 )
#pragma warning( disable : 4267 )
#pragma warning( disable : 4819 )
#pragma warning( disable : 4099 )
#pragma warning( disable : 4996 )
#pragma warning( disable : 4786 )
#pragma warning( disable : 4231 )
//----------------------------------------------------------------------------------------------------------------------------
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif

//----------------------------------------------------------------------------------------------------------------------------
// windows
#ifndef WINVER
#define WINVER 0x0501// xp
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501// xp
#endif
#ifndef _WIN32_WINDOWS
#define _WIN32_WINDOWS 0x0410// Windows 98
#endif
#ifndef _WIN32_IE
#define _WIN32_IE 0x0600// IE6.0
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

//----------------------------------------------------------------------------------------------------------------------------
#include <windows.h>
#include <assert.h>

#define MYSLEEP( ms ) Sleep( ms )
#define MyThreadId()  ::GetCurrentThreadId()

typedef DWORD THREAD_ID;

//----------------------------------------------------------------------------------------------------------------------------
// json
#include <json/json.h>
#ifdef _DEBUG
#pragma comment( lib, "lib_json_d.lib" )
#elif RELEASED
#pragma comment( lib, "lib_json.lib" )
#else
#pragma comment( lib, "lib_json.lib" )
#endif

//----------------------------------------------------------------------------------------------------------------------------
// rapidxml
#include <rapidxml.hpp>
#include <rapidxml_print.hpp>
#include <rapidxml_utils.hpp>

//----------------------------------------------------------------------------------------------------------------------------
// mysql++
#include <mysql++.h>
#ifdef _DEBUG
#pragma comment( lib, "mysqlpp_d.lib" )
#elif RELEASED
#pragma comment( lib, "mysqlpp.lib" )
#else
#pragma comment( lib, "mysqlpp.lib" )
#endif

//----------------------------------------------------------------------------------------------------------------------------
//protobuf
#ifdef _DEBUG
#pragma comment( lib, "libprotobuf.lib" )
#pragma comment( lib, "libprotoc.lib" )
#elif RELEASED
#pragma comment( lib, "libprotobuf.lib" )
#pragma comment( lib, "libprotoc.lib" )
#else
#pragma comment( lib, "libprotobuf.lib" )
#pragma comment( lib, "libprotoc.lib" )
#endif

#else

//----------------------------------------------------------------------------------------------------------------------------
#include <sys/types.h>
#include <pthread.h>
#include <execinfo.h>
#include <signal.h>
#include <exception>
#include <setjmp.h>
#include <sys/epoll.h>

#define MYSLEEP( ms ) usleep( ms*1000 )
#define MyThreadId() pthread_self()

typedef pthread_t THREAD_ID;

#endif

#include <vector>
#include <map>
#include <list>
using namespace std;

#define SINGLETON_CLASS( class_name ) \
	public:	\
	static VOID createInstance(); \
	static VOID destroyInstance(); \
	static class_name *getInstance(); \
	private: \
	static class_name *mpInstance; 

#define IMP_SINGLETON_CLASS( class_name ) \
	class_name * class_name::mpInstance = NULL; \
	VOID class_name::createInstance() \
{ \
	if ( NULL == mpInstance ) \
{ \
	mpInstance = new class_name; \
} \
} \
	VOID class_name::destroyInstance() \
{ \
	if ( NULL != mpInstance ) \
{ \
	delete mpInstance; \
	mpInstance = NULL; \
} \
} \
	class_name *class_name::getInstance() \
{ \
	return mpInstance; \
}

#define  REFLECTION_ENUM( class_name, enum_name ) \
	static boost::unordered_map< std::string, USHORT > mReflection##enum_name; \
	static USHORT get##enum_name( const std::string & key );

#define  IMP_REFLECTION_ENUM_BEGIN( class_name, enum_name ) \
	boost::unordered_map< std::string, USHORT > class_name::mReflection##enum_name; \
	USHORT class_name::get##enum_name( const std::string & key ) \
{ \
	if ( mReflection##enum_name.size() == 0 ) \
{ 
#define REG_REFLECTION_ENUM( class_name, enum_name, type ) \
	mReflection##enum_name[ #type ] = (USHORT)type;
#define IMP_REFLECTION_ENUM_END( class_name, enum_name ) \
} \
	boost::unordered_map< std::string, USHORT >::iterator index = mReflection##enum_name.find( key ); \
	if ( index != mReflection##enum_name.end() ) \
{ \
	return index->second; \
} \
	return 0; \
} 

#define DECLARE_VAR(type, type_name) \
	protected: \
	type type_name; \
	public: \
	type get##type_name() \
	{ \
		return type_name; \
	} \
	void set##type_name(type t) \
	{ \
		type_name = t; \
	}

#define DECLARE_CLASS_VAR(type, type_name) \
	protected: \
	type m_##type_name; \
	public: \
	type get##type_name() \
{ \
	return m_##type_name; \
} \
	void set##type_name(type t) \
{ \
	m_##type_name = t; \
}

#define X_TEST_FLAG(x, bit) (x & BIT(bit))
#define X_SET_FLAG(x, bit) (x |= BIT(bit))
#define X_CLEAR_FLAG(x, bit) (x &= ~BIT(bit))

#define X_PACKET_HEAD_LEN	4
#define X_MAX_PACKET_BODY_LEN	8192
#define X_MSG_HEAD_LEN	4
#define X_MAX_MSG_BODY_LEN	 8188	

#endif //__BASE_H__